package com.demo.main.filter;

import com.demo.main.utils.ServletUtil;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.demo.main.utils.ServletUtil.API_PATH;

// 使用@WebFilter注解声明这是一个Filter，并配置其应用的URL模式
@WebFilter(urlPatterns = {"/api/*", "*.jsp"})
public class AuthorizationFilter implements Filter {
    // 定义一个List集合，用于存储允许通过的路径
    private List<String> allowedPaths;

    // 实现Filter接口的init方法，用于Filter的初始化工作
    @Override
    public void init(FilterConfig filterConfig) {
        // 初始化allowedPaths集合，将指定的路径数组转换为List，并给每个路径添加API_PATH前缀
        allowedPaths = Arrays.stream(new String[]{
                "/public/login",
                "/public/register",
                "/public/logout",
                "/footer",
                "/public/validate"
        }).map(item -> API_PATH + item).collect(Collectors.toList());
    }

    // 实现Filter接口的doFilter方法，用于处理请求和响应的过滤逻辑
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        // 创建ServletUtil实例，用于处理请求和响应中的操作
        ServletUtil servletUtil = new ServletUtil(request, response);
        // 获取当前请求的Servlet路径
        String servletPath = servletUtil.getServletPath();
        // 如果当前请求的路径在allowedPaths集合中，则直接放行
        if (allowedPaths.contains(servletPath)) {
            filterChain.doFilter(request, response);
            return;
        }
        // 如果用户未登录，则重定向到登录页面
        if (!servletUtil.isLogin()) {
            servletUtil.redirectToLogin();
            return;
        }
        // 从会话中获取用户的角色信息
        String role = servletUtil.getSessionRole(String.class);
        // 如果当前请求的路径不以用户角色的路径开头，则重定向到登录页面（这里假设路径中包含了角色信息）
        if (!servletPath.startsWith(API_PATH + "/" + role)) {
            servletUtil.redirectToLogin();
            return;
        }
        // 如果以上条件都不满足，则放行请求
        filterChain.doFilter(request, response);
    }

    // 实现Filter接口的destroy方法，用于Filter的销毁工作
    // 在这里清空allowedPaths集合，释放资源（虽然在这个例子中可能不是必需的，但作为一种良好的实践）
    @Override
    public void destroy() {
        allowedPaths.clear();
    }
}